#include "Parameters.h"

#define fatherNode(node,typeId,number) \
	if ( NULL != node.typeId##_##number){ \
	node.typeId##_##number##->##_parent##=##(&node) ; }
	
#define SetfatherNode(node,typeId) \
	fatherNode(node, typeId,1) \
	fatherNode(node, typeId,2) \
	fatherNode(node, typeId,3) \
	fatherNode(node, typeId,4) \
	fatherNode(node, typeId,6) \
	fatherNode(node, typeId,7) \
	fatherNode(node, typeId,8) \
	fatherNode(node, typeId,9)

#define SetFatherNodeAll(node) \
	SetfatherNode(node,middlelayer); \
	SetfatherNode(node,uplayer); \
	SetfatherNode(node,downlayer)

#define Cost(node,typeId,number) \
	if (node.typeId##_##number != NULL) { \
	node.typeId##_##number##->##H##=##LineCostH(node.typeId##_##number,&grid->Destination,*det); \
	node.typeId##_##number##->##G##=##LineCostG(&grid->Source,node.typeId##_##number,*det); \
	node.typeId##_##number##->##F##=##LineCostF(node.typeId##_##number);}

#define CostOneLayer(node,typeId) \
	Cost(node,typeId,1); \
	Cost(node,typeId,2); \
	Cost(node,typeId,3); \
	Cost(node,typeId,4); \
	Cost(node,typeId,6); \
	Cost(node,typeId,7); \
	Cost(node,typeId,8); \
	Cost(node,typeId,9)

#define CostAll(node) \
	CostOneLayer(node,middlelayer);\
	CostOneLayer(node,uplayer);\
	CostOneLayer(node,downlayer)

#define changeSonNode(node,father,typeId,number) \
	node = father##->##typeId##_##number;

#define changeNode(pSon,pFather,caseType)\
	switch(caseType){ \
	case 0: changeSonNode(pSon,pFather,middlelayer,2) break; \
		case 1: changeSonNode(pSon,pFather,middlelayer,3) break;  \
		case 2: changeSonNode(pSon,pFather,middlelayer,4) break; \
		case 3: changeSonNode(pSon,pFather,middlelayer,6) break; \
		case 4: changeSonNode(pSon,pFather,middlelayer,7) break; \
		case 5: changeSonNode(pSon,pFather,middlelayer,8) break; \
		case 6: changeSonNode(pSon,pFather,middlelayer,9) break; \
		case 7:  changeSonNode(pSon,pFather,uplayer,1) break; \
		case 8:  changeSonNode(pSon,pFather,uplayer,2) break; \
		case 9:  changeSonNode(pSon,pFather,uplayer,3) break; \
		case 10: changeSonNode(pSon,pFather,uplayer,4) break; \
		case 11: changeSonNode(pSon,pFather,uplayer,6) break; \
		case 12: changeSonNode(pSon,pFather,uplayer,7) break; \
		case 13: changeSonNode(pSon,pFather,uplayer,8) break; \
		case 14: changeSonNode(pSon,pFather,uplayer,9) break; \
		case 15: changeSonNode(pSon,pFather,downlayer,1) break; \
		case 16: changeSonNode(pSon,pFather,downlayer,2) break; \
		case 17: changeSonNode(pSon,pFather,downlayer,3) break; \
		case 18: changeSonNode(pSon,pFather,downlayer,4) break; \
		case 19: changeSonNode(pSon,pFather,downlayer,6) break; \
		case 20: changeSonNode(pSon,pFather,downlayer,7) break; \
		case 21: changeSonNode(pSon,pFather,downlayer,8) break; \
		case 22: changeSonNode(pSon,pFather,downlayer,9) break; }

#define NullUpLayer(node,typeId,number) \
	node##.##typeId##_##number = NULL
	
#define Nulllayer(node,typeId) \
	NullUpLayer(node,typeId,1); \
	NullUpLayer(node,typeId,2); \
	NullUpLayer(node,typeId,3); \
	NullUpLayer(node,typeId,4); \
	NullUpLayer(node,typeId,6); \
	NullUpLayer(node,typeId,7); \
	NullUpLayer(node,typeId,8); \
	NullUpLayer(node,typeId,9)

#define ExpandDecidedBranch(Z,Y,X,GRID,DET,node,typeId,number) \
	if( (Z >= nZl) && (Z<=nZu) && (Y >= 0) && (Y < GRID##.##GridDimY) && (X >= 0) && (X < GRID##.##GridDimX ) ){ \
	if (sqrtf(distancePrice( &(*GRID##.##pGridCoordinate)[Z][Y][X],&DET))> pDet##->##_radius){ \
	node##->##typeId##_##number = &(*GRID##.##pGridCoordinate)[Z][Y][X]; } }

#define ExpandDecide(Z,Y,X,GRID,DET,node,typeId) \
	ExpandDecidedBranch(Z,Y-1,X-1,GRID,DET,node,typeId,1) \
	ExpandDecidedBranch(Z,Y-1,X  ,GRID,DET,node,typeId,2) \
	ExpandDecidedBranch(Z,Y-1,X+1,GRID,DET,node,typeId,3) \
	ExpandDecidedBranch(Z,Y  ,X-1,GRID,DET,node,typeId,4) \
	ExpandDecidedBranch(Z,Y  ,X+1,GRID,DET,node,typeId,6) \
	ExpandDecidedBranch(Z,Y+1,X-1,GRID,DET,node,typeId,7) \
	ExpandDecidedBranch(Z,Y+1,X  ,GRID,DET,node,typeId,8) \
	ExpandDecidedBranch(Z,Y+1,X+1,GRID,DET,node,typeId,9) 

#define Expand(Z,Y,X,GRID,DET,node) \
	ExpandDecide(Z,Y,X,GRID,DET,node,middlelayer); \
	ExpandDecide(Z+1,Y,X,GRID,DET,node,uplayer); \
	ExpandDecide(Z-1,Y,X,GRID,DET,node,downlayer) 

#define nodeCheck(node,typeId,number,flag) \
	if (node##.##typeId##_##number != NULL) { ++flag; }

#define CheckAll(node,typeId,flag) \
	nodeCheck(node,typeId,1,flag) \
	nodeCheck(node,typeId,2,flag) \
	nodeCheck(node,typeId,3,flag) \
	nodeCheck(node,typeId,4,flag) \
	nodeCheck(node,typeId,6,flag) \
	nodeCheck(node,typeId,7,flag) \
	nodeCheck(node,typeId,8,flag) \
	nodeCheck(node,typeId,9,flag) 

#define Check(node,flag) \
	CheckAll(node,middlelayer,flag)	\
	CheckAll(node,uplayer,flag)	\
	CheckAll(node,downlayer,flag) 